/*
    SUSAN® - Sole of Unix Save ANything

   
   Copyright (C) 2015-2019 Hechzh Property

   
*/
/* originally was Kern Sibbald, June MMIII */
/*
 * extracted the TEST_PROGRAM functionality from the files in ..
 * and adapted for gtest
 *
 * Philipp Storz, November 2017
 */

#if defined(HAVE_MINGW)
#include "include/susan.h"
#include "gtest/gtest.h"
#else
#include "gtest/gtest.h"
#include "include/susan.h"
#endif

#include "lib/alist.h"

struct FileSet {
  FileSet() = default;
  ~FileSet() = default;

  alist mylist;
};

/*
 * helper functions
 */

void AlistFill(alist* list, int max)
{
  char buf[30];
  int start = 0;

  if (list) { start = list->size(); }

  /*
   * fill list with strings of numbers from 0 to n.
   */
  for (int i = 0; i < max; i++) {
    sprintf(buf, "%d", start + i);
    list->append(strdup(buf));
  }

  /*
   * verify that max elements have been added
   */
  EXPECT_EQ(list->size(), start + max);
}

/*
 * we expect, that the list is filled with strings of numbers from 0 to n.
 */
void TestForeachAlist(alist* list)
{
  char* str = NULL;
  char buf[30];
  int i = 0;

  /*
   * test all available foreach loops
   */

  foreach_alist (str, list) {
    sprintf(buf, "%d", i);
    EXPECT_STREQ(str, buf);
    i++;
  }

  foreach_alist_index (i, str, list) {
    sprintf(buf, "%d", i);
    EXPECT_STREQ(str, buf);
  }

  foreach_alist_rindex (i, str, list) {
    sprintf(buf, "%d", i);
    EXPECT_STREQ(str, buf);
  }
}

/*
 * Tests
 */

void test_alist_init_destroy()
{
  FileSet* fileset;
  fileset = new FileSet;
  fileset->mylist.init();

  AlistFill(&(fileset->mylist), 20);
  for (int i = 0; i < fileset->mylist.size(); i++) {
    EXPECT_EQ(i, atoi((char*)fileset->mylist[i]));
  }
  fileset->mylist.destroy();
  delete fileset;
}


void test_alist_dynamic()
{
  alist* list = NULL;
  char* buf;

  // NULL->size() will segfault
  // EXPECT_EQ(list->size(), 0);

  // does foreach work for NULL?
  TestForeachAlist(list);

  // create empty list, which is prepared for a number of entires
  list = new alist(10);
  EXPECT_EQ(list->size(), 0);

  // does foreach work for empty lists?
  TestForeachAlist(list);

  // fill the list
  AlistFill(list, 20);
  TestForeachAlist(list);

  // verify and remove the latest entries
  EXPECT_EQ(list->size(), 20);
  buf = (char*)list->pop();
  EXPECT_STREQ(buf, "19");
  free(buf);

  EXPECT_EQ(list->size(), 19);
  buf = (char*)list->pop();
  EXPECT_STREQ(buf, "18");
  free(buf);

  // added more entires
  AlistFill(list, 20);
  TestForeachAlist(list);

  EXPECT_EQ(list->size(), 38);

  delete (list);
}


/*
 * main entry point
 */

TEST(alist, alist)
{
  test_alist_init_destroy();
  test_alist_dynamic();
}
